// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StorageAdapterTest.cs" company="">
//   
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Tests
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;

    using ExecutionTool.ImportExport;
    using ExecutionTool.Profile;

    using Microsoft.Practices.EnterpriseLibrary.Logging;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.StorageClient;

    using Moq;

    [TestClass]
    public class StorageAdapterTest
    {
        #region Fields

        private AzureStorageLocation target;

        #endregion

        #region Public Methods and Operators

        [TestMethod]
        public void CanCheckBlobExistOrNot()
        {
            var loggerMock = new Mock<LogWriter>();
            var adapter = new StorageAdapter(loggerMock.Object);
            var result = adapter.BlobExists(this.target, "bacpac/poc_512m.bacpac");

            Assert.IsTrue(result);
        }

        [TestMethod]
        [Ignore]
        public void CanCreateContainerIfNotExist()
        {
            var loggerMock = new Mock<LogWriter>();
            var adapter = new StorageAdapter(loggerMock.Object);
            var task = adapter.CreateContainerIfNotExistAsync(this.target, "unittest");
            task.Wait();

            Assert.IsTrue(StorageHelper.ContainerExists(this.target.StorageAccount, this.target.AccessKey, "unittest"));
            StorageHelper.DeleteContainer(this.target.StorageAccount, this.target.AccessKey, "unittest");
        }

        [TestMethod]
        public void CanListBlobsUnderContainer()
        {
            var loggerMock = new Mock<LogWriter>();
            var adapter = new StorageAdapter(loggerMock.Object);
            var results = adapter.ListBlobs(this.target, "bacpac");

            foreach (var blob in results)
            {
                Console.WriteLine("{0}: {1}", blob.Uri, blob.Properties.LastModifiedUtc);
            }
        }

        [TestMethod]
        [Ignore]
        public void CanSetMetadata()
        {
            var metadata = new Dictionary<string, string> { { "DatabaseName", "DatabaseName" }, { "Edition", "Web" }, { "MaxSizeInGb", "1" } };
            var loggerMock = new Mock<LogWriter>();
            var adapter = new StorageAdapter(loggerMock.Object);
            adapter.SetMetadata(this.target, "bacpac/poc_512m.bacpac", metadata);
        }

        [TestMethod]
        public void CanTestConnection()
        {
            var loggerMock = new Mock<LogWriter>();
            var adapter = new StorageAdapter(loggerMock.Object);
            adapter.TestConnection(this.target);
        }

        [TestInitialize]
        public void Setup()
        {
            this.target = new AzureStorageLocation
                {
                    StorageAccount = "dataprotectorpoc", 
                    AccessKey = "Oz8JVCBWmDvJBoIIiKVCLtzapCeHo7ZaV5Edvfq7Jl7NeUGjkCyUGV4gKmjLB6/Wq6dpDMdKtRbdj31mKIx7DQ==", 
                };
        }

        [TestMethod]
        public void TestBlobStream()
        {
            // Create service client for credentialed access to the Blob service.
            var blobClient = new CloudBlobClient(
                string.Format("https://{0}.blob.core.windows.net/", this.target.StorageAccount), 
                new StorageCredentialsAccountAndKey(this.target.StorageAccount, this.target.AccessKey));

            var blobRef = blobClient.GetBlobReference("bacpac/poc_512m.bacpac");

            using (var stream = blobRef.OpenRead())
            {
                Console.WriteLine("CanSeek: {0}", stream.CanSeek);
                Console.WriteLine("Length: {0}", stream.Length);

                ////Console.WriteLine("BlockSize: {0}", stream.BlockSize);
                var tasks = new List<Task>();
                for (var i = 0; i < 5; i++)
                {
                    var j = i;
                    var t = Task.Factory.StartNew(
                        () =>
                            {
                                Thread.Sleep(500);
                                stream.Seek(j * 1024, SeekOrigin.Begin);
                                Console.WriteLine("{0}:{1}:{2}", j, Thread.CurrentThread.ManagedThreadId, stream.Position);
                            });

                    tasks.Add(t);
                }

                Task.WaitAll(tasks.ToArray());
            }
        }

        #endregion
    }
}
